package org.xxpay.pay.channel.xxpay;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.xxpay.core.common.constant.MchConstant;
import org.xxpay.core.common.constant.PayConstant;
import org.xxpay.core.common.util.MyLog;
import org.xxpay.core.common.util.XXPayUtil;
import org.xxpay.core.entity.PayOrder;
import org.xxpay.pay.channel.BasePayNotify;

import javax.servlet.http.HttpServletRequest;

/**
 * @description: xxpay
 */
@Service
public class XxpayPayNotifyService extends BasePayNotify {

    private static final MyLog _log = MyLog.getLog(XxpayPayNotifyService.class);
    private static final String logPrefix = "【处理xxpay支付回调】";


    @Override
    public String getChannelName() {
        return XxpayConfig.CHANNEL_NAME;
    }

    @Override
    public JSONObject doNotify(Object notifyData) {

        _log.info("====== 开始处理xxpay支付回调通知 ======");
        HttpServletRequest req = (HttpServletRequest) notifyData;
        JSONObject retObj = new JSONObject();

        PayOrder payOrder = verifyAliPayParams(req);
        if( payOrder == null ) { //验证参数失败
            retObj.put(PayConstant.RESPONSE_RESULT, PayConstant.RETURN_ALIPAY_VALUE_FAIL);
            return retObj;
        }

        //订单已经支付完成
        if(payOrder.getStatus() == PayConstant.PAY_STATUS_SUCCESS || payOrder.getStatus() == PayConstant.PAY_STATUS_COMPLETE){
            retObj.put(PayConstant.RESPONSE_RESULT, PayConstant.RETURN_ALIPAY_VALUE_SUCCESS);
            return retObj;
        }

        //上游通知 状态
        long reqStatus = Long.parseLong(req.getParameter("status"));
        String channelOrderNo = req.getParameter("payOrderId"); //上游订单号
        String channelAttach = req.getParameter("channelAttach");

        //支付成功
        if(reqStatus == PayConstant.PAY_STATUS_SUCCESS){

            int updatePayOrderRows = commonService.payOrderService.updateStatus4Success(payOrder.getPayOrderId(), channelOrderNo, channelAttach);
            if (updatePayOrderRows != 1) {
                _log.error("{}更新支付状态失败,将payOrderId={},更新payStatus={}失败", logPrefix, payOrder.getPayOrderId(), PayConstant.PAY_STATUS_SUCCESS);
                retObj.put(PayConstant.RESPONSE_RESULT, "处理订单失败");
                return retObj;
            }
            _log.error("{}更新支付状态成功,将payOrderId={},更新payStatus={}成功", logPrefix, payOrder.getPayOrderId(), PayConstant.PAY_STATUS_SUCCESS);
            payOrder.setStatus(PayConstant.PAY_STATUS_SUCCESS);

            // 业务系统后端通知
            baseNotify4MchPay.doNotify(payOrder, true);

            retObj.put(PayConstant.RESPONSE_RESULT, PayConstant.RETURN_ALIPAY_VALUE_SUCCESS);
            return  retObj;
        }else{ //其他状态

            _log.error("{}返回状态为{}，不进行任何处理", logPrefix, reqStatus);
            retObj.put(PayConstant.RESPONSE_RESULT, PayConstant.RETURN_ALIPAY_VALUE_FAIL);
            return retObj;
        }
    }

    /**
     * 验证通知参数
     * @return
     */
    private PayOrder verifyAliPayParams(HttpServletRequest req) {

        //验证参数是否合法
        String payOrderId = req.getParameter("payOrderId");
        String myselfOrderId = req.getParameter("mchOrderNo");
        String amount = req.getParameter("amount");
        String status = req.getParameter("status");

        _log.info("{}验证参数payOrderId={}, myselfOrderId={}, amount={}, status={}", logPrefix, payOrderId, myselfOrderId, amount, status);

        if(StringUtils.isAnyEmpty(payOrderId, myselfOrderId, amount, status)){
            _log.error("{}必要参数为空payOrderId={}, myselfOrderId={}, amount={}, status={}", logPrefix, payOrderId, myselfOrderId, amount, status);
            return null;
        }

        PayOrder payOrder = commonService.payOrderService.findByPayOrderId(myselfOrderId); //根据myselfOrderId查单
        if(payOrder == null){
            _log.error("{}查单失败myselfOrderId={}", logPrefix, myselfOrderId);
            return null;
        }

        Long amountL = Long.parseLong(amount);
        if(!amountL.equals(payOrder.getAmount())){
            _log.error("{}订单金额验证失败， myselfAmount={}, amount={}", logPrefix, payOrder.getAmount(), amount);
            return null;
        }

        JSONObject reqDataJSON = new JSONObject();
        reqDataJSON.put("payOrderId", req.getParameter("payOrderId"));
        reqDataJSON.put("mchId", req.getParameter("mchId"));
        reqDataJSON.put("appId", req.getParameter("appId"));
        reqDataJSON.put("productId", req.getParameter("productId"));
        reqDataJSON.put("mchOrderNo", req.getParameter("mchOrderNo"));
        reqDataJSON.put("amount", req.getParameter("amount"));
        reqDataJSON.put("income", req.getParameter("income"));
        reqDataJSON.put("status", req.getParameter("status"));
        reqDataJSON.put("channelOrderNo", req.getParameter("channelOrderNo"));
        reqDataJSON.put("channelAttach", req.getParameter("channelAttach"));
        reqDataJSON.put("param1", req.getParameter("param1"));
        reqDataJSON.put("param2", req.getParameter("param2"));
        reqDataJSON.put("paySuccTime", req.getParameter("paySuccTime"));
        reqDataJSON.put("backType", req.getParameter("backType"));
        reqDataJSON.put("sign", req.getParameter("sign"));

        XxpayConfig xxpayConfig = new XxpayConfig(getPayParam(payOrder));
        if(! XXPayUtil.verifyPaySign(reqDataJSON, xxpayConfig.getKey())){
            _log.error("{}验签失败", logPrefix);
            return null;
        }

        return payOrder;
    }
}
